package com.storm.future.advisor;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.DynamicIntroductionAdvice;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.IntroductionInterceptor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author gu
 * @date 2020/5/15 11:04
 */
@Component
public class EngineerIntroductionAdvisor implements IntroductionAdvisor {


    @Override
    public ClassFilter getClassFilter() {
        return new EngineerPointcut().getClassFilter();
    }

    @Override
    public void validateInterfaces() throws IllegalArgumentException {

    }

    @Override
    public Advice getAdvice() {
        return new IntroductionInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                Method method = invocation.getMethod();
                Object aThis = invocation.getThis();
                Object[] arguments = invocation.getArguments();
                Object invoke = null;
                if(implementsInterface(method.getDeclaringClass())){
                    new RepairInvoker(aThis).repair();
                }else {
                    invoke = method.invoke(aThis, arguments);
                }
                return invoke;
            }

            @Override
            public boolean implementsInterface(Class<?> intf) {
                if (intf == Repair.class) {
                    return true;
                }
                return false;
            }
        };
    }

    @Override
    public boolean isPerInstance() {
        return false;
    }

    @Override
    public Class<?>[] getInterfaces() {
        return new Class<?>[]{Repair.class};
    }
}
